package com.yc.testupload.controller;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import com.yc.testupload.util.DatabaseUtil;

/**
 * 素材插入Servlet
 * 处理从素材库选择的素材并随机顺序插入到wenku和file表
 */
@WebServlet("/api/insert-materials")
public class MaterialInsertServlet extends HttpServlet {
    private static final Logger logger = LogManager.getLogger(MaterialInsertServlet.class);

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        JSONObject resultJson = new JSONObject();

        try {
            // 读取请求体
            StringBuilder sb = new StringBuilder();
            BufferedReader reader = request.getReader();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            String requestBody = sb.toString();
            JSONObject requestJson = new JSONObject(requestBody);

            // 获取选中的素材列表
            JSONArray materialsArray = requestJson.getJSONArray("materials");
            logger.info("接收到待插入素材数量: {}", materialsArray.length());

            // 从会话中获取当前登录用户的user_id
            Integer userId = (Integer) request.getSession().getAttribute("userId");
            if (userId == null) {
                userId = 0; // 默认值
                logger.warn("会话中未找到有效的用户ID，使用默认值{}", userId);
            }

            // 插入素材并获取成功数量
            int successCount = insertMaterialsToDatabase(userId, materialsArray);

            // 构建响应结果
            resultJson.put("code", 0);
            resultJson.put("message", "素材插入成功");
            resultJson.put("successCount", successCount);
            resultJson.put("totalCount", materialsArray.length());

            response.setStatus(HttpServletResponse.SC_OK);

        } catch (Exception e) {
            logger.error("插入素材失败: {}", e.getMessage(), e);
            resultJson.put("code", 1);
            resultJson.put("message", "插入素材失败: " + e.getMessage());
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        } finally {
            out.write(resultJson.toString());
            out.flush();
            out.close();
        }
    }

    /**
     * 将素材随机顺序插入到wenku和file表
     */
    private int insertMaterialsToDatabase(Integer userId, JSONArray materialsArray) {
        int successCount = 0;
        Connection conn = null;

        try {
            // 获取数据库连接
            conn = DatabaseUtil.getConnection();
            
            // 转换JSONArray为List，以便进行随机排序
            List<JSONObject> materialsList = new ArrayList<>();
            for (int i = 0; i < materialsArray.length(); i++) {
                materialsList.add(materialsArray.getJSONObject(i));
            }
            
            // 随机排序素材列表
            Collections.shuffle(materialsList);
            logger.info("素材列表已随机排序");

            // 遍历随机排序后的素材列表并插入
            for (JSONObject material : materialsList) {
                String title = material.getString("title");
                String content = material.getString("content");
                conn.setAutoCommit(false); // 开始事务

                try {
                    // 插入到file表
                    int fileId = insertIntoFileTable(conn, userId, title, content);
                    if (fileId > 0) {
                        // 插入到wenku表
                        boolean wenkuInserted = insertIntoWenkuTable(conn, userId, title, fileId);
                        if (wenkuInserted) {
                            successCount++;
                            logger.info("素材插入成功 - 标题: {}", title);
                        }
                    }
                    conn.commit(); // 每插入一个素材就提交一次事务
                } catch (SQLException e) {
                    logger.error("插入素材失败 - 标题: {}, 错误: {}", title, e.getMessage());
                    try {
                        conn.rollback();
                    } catch (SQLException rollbackEx) {
                        logger.error("回滚事务失败: {}", rollbackEx.getMessage());
                    }
                }
            }

        } catch (SQLException e) {
            logger.error("数据库操作异常: {}", e.getMessage());
            try {
                if (conn != null) {
                    conn.rollback();
                }
            } catch (SQLException rollbackEx) {
                logger.error("回滚事务失败: {}", rollbackEx.getMessage());
            }
        } finally {
            if (conn != null) {
                try {
                    conn.setAutoCommit(true); // 恢复默认设置
                    conn.close();
                } catch (SQLException e) {
                    logger.error("关闭数据库连接失败: {}", e.getMessage());
                }
            }
        }

        logger.info("素材插入完成，成功插入 {} 个，共 {} 个", successCount, materialsArray.length());
        return successCount;
    }

    /**
     * 插入数据到file表
     */
    private int insertIntoFileTable(Connection conn, Integer userId, String title, String content) throws SQLException {
        int fileId = -1;
        String fileSql = "INSERT INTO wk_file (file_md5, file_url, ben_file, file_name, file_size, file_ext, user_id) VALUES (?, ?, ?, ?, ?, ?, ?)";

        // 由于是从素材库插入，这里使用简化的文件信息
        String fileMd5 = "material_" + System.currentTimeMillis() + "_" + (int)(Math.random() * 1000);
        String fileUrl = content; // 使用素材内容作为file_url
        String benFile = content; // 使用素材内容作为ben_file
        String fileName = title + ".txt";
        long fileSize = content.length();
        String fileExt = "txt";

        try (PreparedStatement pstmt = conn.prepareStatement(fileSql, PreparedStatement.RETURN_GENERATED_KEYS)) {
            pstmt.setString(1, fileMd5);
            pstmt.setString(2, fileUrl);
            pstmt.setString(3, benFile);
            pstmt.setString(4, fileName);
            pstmt.setLong(5, fileSize);
            pstmt.setString(6, fileExt);
            pstmt.setInt(7, userId);

            int rowsAffected = pstmt.executeUpdate();
            if (rowsAffected > 0) {
                try (ResultSet generatedKeys = pstmt.getGeneratedKeys()) {
                    if (generatedKeys.next()) {
                        fileId = generatedKeys.getInt(1);
                    }
                }
            }
        }

        return fileId;
    }

    /**
     * 插入数据到wenku表
     */
    private boolean insertIntoWenkuTable(Connection conn, Integer userId, String title, int fileId) throws SQLException {
        String wenkuSql = "INSERT INTO wk_wenku (title, user_id, wen_type, file_id, file_jine, type_id, add_time, edit_time, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";

        // 设置参数
        String documentType = "free"; // 默认设置为免费文档
        BigDecimal priceValue = BigDecimal.ZERO;
        int typeId = 1; // 默认分类ID
        long currentTime = System.currentTimeMillis() / 1000; // 当前时间戳（秒）

        try (PreparedStatement pstmt = conn.prepareStatement(wenkuSql)) {
            pstmt.setString(1, title);
            pstmt.setInt(2, userId);
            pstmt.setString(3, documentType);
            pstmt.setInt(4, fileId);
            pstmt.setBigDecimal(5, priceValue);
            pstmt.setInt(6, typeId);
            pstmt.setLong(7, currentTime);
            pstmt.setLong(8, currentTime);
            pstmt.setInt(9, 1); // 状态为1（正常）

            int rowsAffected = pstmt.executeUpdate();
            return rowsAffected > 0;
        }
    }
}